package com.erp.erp_ui.email;

import com.erp.erp_entitys.Email.*;
import com.erp.erp_servers.Email.EmailService;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;

class SendEmail {
    /*
     //发件人地址
     public static String senderAddress = "xxx@163.com";
     //收件人地址
     public static String recipientAddress = "xxx@qq.com";
     //发件人账户名
     public static String senderAccount = "xxx";
     //发件人账户密码
     public static String senderPassword = "xxx";
     */
    public static Session smtptest(email_smtp smtp) throws MessagingException {
        //1、连接邮件服务器的参数配置
        Properties props = new Properties();
        //设置用户的认证方式
        props.setProperty("mail.smtp.auth", "true");
        //设置传输协议
        props.setProperty("mail.transport.protocol","smtp");
        //设置发件人的SMTP服务器地址
        props.setProperty("mail.smtp.host", smtp.getSmtp_server());
        //2、创建定义整个应用程序所需的环境信息的 Session 对象
        Session session = Session.getInstance(props);
        //4、根据session对象获取邮件传输对象Transport
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // 使用JSSE的SSL
        props.put("mail.smtp.socketFactory.fallback", "false"); // 只处理SSL的连接,对于非SSL的连接不做处理
       return session;
    }

    public static void sendEmail(email_smtp smtp, email_message message, EmailService emailService, email_deploy deploy) throws Exception {
        //1、连接邮件服务器的参数配置
        Properties props = new Properties();
        //设置用户的认证方式
        props.setProperty("mail.smtp.auth", "true");
        //设置传输协议
        props.setProperty("mail.transport.protocol","smtp");
        //尝试附件名称发送乱码问题
        props.setProperty("mail.mime.splitlongparameters","false");
        //设置发件人的SMTP服务器地址
        props.setProperty("mail.smtp.host", smtp.getSmtp_server());
        //2、创建定义整个应用程序所需的环境信息的 Session 对象
        Session session = Session.getInstance(props);
        //设置调试信息在控制台打印出来
        session.setDebug(true);
        //3、创建邮件的实例对象
        MimeMessage mim = getMimeMessage(session, message, smtp,deploy);
        //这里来控制群发还是单发
        if (message.getIsmore()==1) {//单发
            //设置邮件主题
            String subject = MimeUtility.encodeWord(message.getSubject(),  message.getCharset(), "Q");
            mim.setSubject(subject);
            //设置邮件发送对象
            /* 设置收件人地址（可以增加多个收件人、抄送、密送），即下面这一行代码书写多行
         MimeMessage.RecipientType.TO;//发送
         MimeMessage.RecipientType.CC;//抄送
         MimeMessage.RecipientType.BCC;//密送
         */
            int con=0;//收件人控制器
            Iterator<Map.Entry<String, String>> iterator = message.getSendAddres().entrySet().iterator();
            String sendAdd=null;
            String sendName=null;
            while(iterator.hasNext()){
                Map.Entry<String, String> next = iterator.next();
                if(con==0){
                    mim.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(next.getValue()));
                    con++;
                    sendAdd+=next.getValue()+";";
                    sendName+=next.getKey()+";";
                }else{
                    mim.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(next.getValue()));
                    sendAdd+=next.getValue()+";";
                    sendName+=next.getKey()+";";
                }
            }
            String copyAdd=null;
            if (message.getCopyAddress().size()>0) {
                for (String cop : message.getCopyAddress()) {
                    if(cop!=""){
                        mim.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(cop));
                        copyAdd+=cop+";";
                    }
                }
            }
            String DarkAdd=null;
            if (message.getDarkAddress().size()>0) {
                for (String dar : message.getDarkAddress()) {
                    if(dar!=""){
                        mim.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(dar));
                        DarkAdd+=dar+";";
                    }

                }
            }
            mim.setFrom(smtp.getEmail_adress());
            Message msg = (Message) mim;
            //4、根据session对象获取邮件传输对象Transport
            Transport transport = session.getTransport();
            //设置发件人的账户名和密码
            transport.connect(smtp.getEmail_name(), smtp.getEmail_password());
            //发送邮件，并发送到所有收件人地址，message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
            transport.sendMessage(msg, msg.getAllRecipients());
            //5、关闭邮件连接
            transport.close();
            //存入数据库
            email_email email=new email_email(-1,smtp.getSmtp_server(),-1,-1,-1,-1,5,message.getSubject(),smtp.getSmtp_name(),smtp.getEmail_adress(),sendName,sendAdd,null,copyAdd,DarkAdd,msg.getSize(),smtp.getEmail_code(),null, EmailUnit.getNowSqlDate(), EmailUnit.getNowSqlDate(),message.getCharset(),1,smtp.getSmtp_id(),-1,message.getPictures().size(),message.getAduncts().size(),0,null,0);
            emailService.addEmail_email(email);
        } else {//群发  需要考试时间因素
            List<String> subjects = message.getSubjects();
            String subj=null;
            String sendN=null;
            String sendA=null;
            for(String s:subjects){
                subj+=s+";";
            }
            int index = 0;//用来控制主题的循环
            Map<String, String> sendAddress = message.getSendAddress();
            Set<Map.Entry<String, String>> entries = sendAddress.entrySet();
            Iterator<Map.Entry<String, String>> iterator = entries.iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, String> next = iterator.next();//发送地址  key=用户名 value=地址
                mim.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(next.getValue()));
                String subject = MimeUtility.encodeWord(subjects.get(index),  message.getCharset(), "Q");
                mim.setSubject(subject);
                index++;
                //控制主题循环
                if (index == subjects.size()) {
                    index = 0;
                }
                Message msg = (Message) mim;
                //4、根据session对象获取邮件传输对象Transport
                Transport transport = session.getTransport();
                //设置发件人的账户名和密码
                transport.connect(smtp.getEmail_name(), smtp.getEmail_password());
                //发送邮件，并发送到所有收件人地址，message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
                transport.sendMessage(msg, msg.getAllRecipients());
                //5、关闭邮件连接
                transport.close();
                int picNum=0;
                int aduNum=0;
                if(message.getPictures()!=null){
                    picNum=message.getPictures().size();
                }
               if(message.getAduncts()!=null){
                    aduNum=message.getAduncts().size();
               }
                email_email email=new email_email(-1,smtp.getSmtp_server(),-1,-1,-1,-1,1,subjects.get(index),smtp.getSmtp_name(),smtp.getEmail_adress(),next.getKey(),next.getValue(),null,null,null,msg.getSize(),smtp.getEmail_code(),null, EmailUnit.getNowSqlDate(), EmailUnit.getNowSqlDate(),message.getCharset(),1,-1,-1,picNum,aduNum,0,null,0);
                emailService.addEmail_email(email);
                sendN+=next.getKey()+";";
                sendA+=next.getValue()+";";
                //群发间隔时间
                Integer momStart = deploy.getMomStart();
                if(momStart==null){
                    momStart=1;
                }
                Integer momEnd = deploy.getMomEnd();
                if(momEnd==null){
                    momEnd=3;
                }
                Random random = new Random();
                int s = random.nextInt(momEnd)%(message.getMomEnd()-momStart+1) + message.getMomStart();
                Thread.sleep(s);
            }
            String adjName = null;
            if(message.getAduncts()!=null){
                Iterator<Map.Entry<String, String>> iterator1 = message.getAduncts().entrySet().iterator();
                while(iterator1.hasNext()){
                    Map.Entry<String, String> next = iterator1.next();
                    adjName+=next.getKey()+";";
                }
            }
            email_mass mass=new email_mass(subj, EmailUnit.getNowSqlDate(),sendN,sendA,message.getContenct(),adjName);
            emailService.insertEmail_mass(mass);
        }
    }
    /**
     * 获得创建一封邮件的实例对象
     *
     * @param session
     * @return
     * @throws MessagingException
     * @throws AddressException
     */
    public static MimeMessage getMimeMessage(Session session, email_message message, email_smtp smtp, email_deploy deploy) throws Exception {
        //1.创建一封邮件的实例对象
        MimeMessage msg = new MimeMessage(session);
        //2.设置发件人地址
        msg.setFrom(new InternetAddress(smtp.getEmail_name()));

        if (message.getPictures()==null && message.getAduncts()==null) {
            msg.setContent(message.getContenct(), "text/html;charset=UTF-8");
        } else if (message.getPictures() != null && message.getAduncts() == null) {
            // 6. 创建文本"节点"
            MimeBodyPart text = new MimeBodyPart();
            // 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
            text.setContent(message.getContenct(), "text/html;charset=UTF-8");
            // 7. （文本+图片）设置 文本 和 图片"节点"的关系（将 文本 和 图片"节点"合成一个混合"节点"）
            MimeMultipart mm_text_image = new MimeMultipart();
            mm_text_image.addBodyPart(text);
            List<MimeBodyPart> parts = keepPicture(message.getPictures());
            for (MimeBodyPart m : parts) {
                mm_text_image.addBodyPart(m);
            }
            mm_text_image.setSubType("related"); // 关联关系
            msg.setContent(mm_text_image);
        } else if (message.getPictures()==null && message.getAduncts() != null) {

            // 6. 创建文本"节点"
            MimeBodyPart text = new MimeBodyPart();
            // 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
            text.setContent(message.getContenct(), "text/html;charset=UTF-8");
            //创建附件“节点”
            MimeMultipart mm = new MimeMultipart();
            mm.addBodyPart(text);
            List<MimeBodyPart> parts = keepAdjunct(message.getAduncts());
            for (MimeBodyPart m : parts) {
                mm.addBodyPart(m);     // 如果有多个附件，可以创建多个多次添加
            }
            mm.setSubType("mixed");         // 混合关系
            msg.setContent(mm);
        } else if (message.getPictures()!= null&& message.getAduncts()!= null) {

            // 6. 创建文本"节点"
            MimeBodyPart text = new MimeBodyPart();
            // 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
            text.setContent(message.getContenct(), "text/html;charset=UTF-8");
            // 7. （文本+图片）设置 文本 和 图片"节点"的关系（将 文本 和 图片"节点"合成一个混合"节点"）
            MimeMultipart mm_text_image = new MimeMultipart();
            mm_text_image.addBodyPart(text);
            List<MimeBodyPart> picts = keepPicture(message.getPictures());

            for (MimeBodyPart pic : picts) {
                mm_text_image.addBodyPart(pic);
            }
            mm_text_image.setSubType("related");    // 关联关系
            // 8. 将 文本+图片 的混合"节点"封装成一个普通"节点"
            // 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart,
            // 上面的 mailTestPic 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
            MimeBodyPart text_image = new MimeBodyPart();
            text_image.setContent(mm_text_image);
            // 10. 设置（文本+图片）和 附件 的关系（合成一个大的混合"节点" / Multipart ）
            MimeMultipart mm = new MimeMultipart();
            mm.addBodyPart(text_image);
            List<MimeBodyPart> adjs = keepAdjunct(message.getAduncts());
            for (MimeBodyPart adj : adjs) {
                mm.addBodyPart(adj);
            }
            mm.setSubType("mixed");         // 混合关系
            msg.setContent(mm);
        }
        //设置邮件的发送时间,默认立即发送
        Date date=new Date();
        msg.setSentDate(date);
        return msg;
    }
    //正文图片处理
    public static List<MimeBodyPart> keepPicture(Map<String, String> pictures) throws MessagingException {
        List<MimeBodyPart> pics = new ArrayList<>();
        Set<Map.Entry<String, String>> entrySet = pictures.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> next = iterator.next();
            String cid = next.getKey();//cid
            String address = next.getValue();//绝对地址
            // 5. 创建图片"节点"
            MimeBodyPart image = new MimeBodyPart();
            // 读取本地文件
            File file=new File(address);
            DataHandler dh = new DataHandler(new FileDataSource(file));
            // 将图片数据添加到"节点"
            image.setDataHandler(dh);
            // 为"节点"设置一个唯一编号（在文本"节点"将引用该ID）
            cid=cid.split("cid:")[1];
            image.setContentID(cid);
            pics.add(image);
        }
        return pics;
    }
    //附件处理
    public static List<MimeBodyPart> keepAdjunct(Map<String, String> aduncts) throws MessagingException, UnsupportedEncodingException {
        List<MimeBodyPart> adjus = new ArrayList<>();
        Set<Map.Entry<String, String>> entries = aduncts.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> next = iterator.next();
            String name = next.getKey();
            String address = next.getValue();
            // 9. 创建附件"节点"
            MimeBodyPart attachment = new MimeBodyPart();
            // 读取本地文件
            File file=new File(next.getValue());
            DataHandler dh2 = new DataHandler(new FileDataSource(file));
            // 将附件数据添加到"节点"
            attachment.setDataHandler(dh2);
            // 设置附件的文件名（需要编码）
            attachment.setFileName(MimeUtility.encodeWord(name));
            adjus.add(attachment);
        }
        return adjus;
    }

    //保存一封邮件到服务器：一般用作保存草稿及审批方面    实现思路，将邮件拆分成email_email  和adjuct
    public static void keepEmail(email_message message){
        int email_class=-1;
        if(message.getIsmore()==1){
        email_class=3;
        }else{
            email_class=4;
        }
        String subj=null;//主题
        String sendA=null;//发送地址
        String copyA=null;//抄送地址
        String darkA=null;//暗送地址
        if (email_class==3){//单发
            subj=message.getSubject();
            Iterator<Map.Entry<String, String>> iterator = message.getSendAddres().entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<String, String> next = iterator.next();
                sendA+=next.getValue()+";";
            }
            for (String cop:message.getCopyAddress()){
                copyA+=cop+";";
            }
            for(String dark:message.getDarkAddress()){
                darkA+=dark+";";
            }
        }else{
                for(String su:message.getSubjects()){
                    subj+=su+";";
                }
            Iterator<Map.Entry<String, String>> iterator = message.getSendAddress().entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<String, String> next = iterator.next();
                sendA+=next.getValue()+";";
            }
        }
        int picNum=0;
        int adjNum=0;
        if(message.getPictures()!=null){
            picNum=message.getPictures().size();
        }
        if(message.getAduncts()!=null){
            adjNum=message.getAduncts().size();
        }
        email_email email=new email_email(-1,null,-1,-1,-1,-1,email_class,subj,null,null,null,sendA,null,copyA,darkA,0,"ceil",null,null,null,message.getCharset(),0,-1,-1,picNum,adjNum,1,null,0);
        //邮件插入数据库，返回id
        int emailID=0;
        email_adjunct adjuct1=new email_adjunct(emailID,0,0,1,null,message.getContenct(),null,null,null,null,0);//正文
        List<email_adjunct> adjuct2=new ArrayList<>();//正文图片 图片要保存到本地，并且返回路径
        Map<String, String> pictures = message.getPictures();//key为cid value为ftp路径
        Iterator<Map.Entry<String, String>> iterator = pictures.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, String> next = iterator.next();
            adjuct2.add(new email_adjunct(emailID,1,0,0,next.getKey(),null,null,next.getValue(),null,null,0));
        }
        Map<String, String> aduncts = message.getAduncts();//key为附件名，value为ftp路径
        List<email_adjunct> adjuct3=new ArrayList<>();//附件
        Iterator<Map.Entry<String, String>> iterator1 = aduncts.entrySet().iterator();
        while(iterator1.hasNext()){
            Map.Entry<String, String> next = iterator1.next();
            adjuct3.add(new email_adjunct(emailID,0,1,0,null,null,null,null,next.getKey(),next.getValue(),0));
        }
        //数据库保存数据
    }
}